<?php

Raise::load('core.ui.RaisePage');
Raise::load('control.RaiseTable');

abstract class RaiseScaffoldPage extends RaisePage {
    
    /**
     * Name of the RaiseDbModel this scaffold page builds for
     * @var string
     */
    private $workingModel;
    
    /**
     *
     * @var RaiseDbConnection
     */
    private $connection;
    
    /**
     *
     * @var RaiseUrl
     */
    private $url;
    
    function __construct($p = null, $model = null) {
        RaiseTemplate::loadTemplate(new RaiseFile(RaisePath::combine(__DIR__, 'scaffoldPageTemplate.html')));
        parent::__construct($p, 'scaffoldPageTemplate');
        if($model){
            $this->workingModel = $model;
        }
    }
    
    /**
     * Prepare the page
     * @param RaiseApplication $app 
     */
    protected function prepare($app) {
        parent::prepare($app);
        $this->url = $app->request()->url();
        $this->connection = new RaiseDbConnection($app->settings(), 'scaffold.default');
        $this->define('connection', $app->settings()->get('Database', 'scaffold.default'));
    }
    
    protected function build() {
        $this->buildNavigation();
        $option = $this->params()->get('opt');
        switch($option){
            case 'add':
                $this->buildAdd();
                break;
            case 'edit':
                $this->buildEdit();
                break;
            case 'delete':
                $this->buildDelete();
                break;
            default:
                $page = $this->params()->get('page') ? $this->param()->get('page') : 1;
                $this->buildList($page);
                break;
        }
        $this->define('model.name', $this->workingModel);
    }
    
    private function buildNavigation(){
        $this->define('navigation', '<a href="">List</a><a href="">Add</a><a href="">Clear</a>');
    }
    
    /**
     * fetch the model
     * @return RaiseDbModel 
     */
    private function fetchModel(){
        return new $this->workingModel($this->connection);
    }
    
    private function buildAdd(){
        $this->define('output', '');
    }
    
    private function buildEdit(){
        $this->define('output', '');
    }
    
    /**
     *
     * @param RaiseDbModel $model
     * @return string 
     */
    private function prepareUrlPK($model){
        $s = '';
        if($model->isCompositePrimaryKey()){
            $a = array();
            foreach($model->primaryKey() as $key){
                $a[] = RaiseUrl::encode($key) . ':' . RaiseUrl::encode($model->$key);
            }
            $s = implode(';', $a);
        }else{
            $s = RaiseUrl::encode($model->{$model->primaryKey()});
        }
        return $s;
    }
    
    private function buildList($page){
        $this->title($this->workingModel . ' - phpRaise Scaffolding');
        
        $recordsPerPage = 20;
        $model = $this->fetchModel();
        $condition = new RaiseDbSqlQueryCondition();
        $condition->offset(($page - 1) * $recordsPerPage);
        $condition->limit($recordsPerPage);
        $records = $model->find($condition);
        
        $table = new RaiseTable();
        $data = new RaiseCollection();
        foreach($records as $record){
            $row = $record->get($this->workingModel);
            $drow = array();
            foreach($row as $col => $attr){
                $drow[$col] = $attr;
            }
            $editUrl = $this->url->raiseClone();
            $editUrl->params(array(
                'opt' => 'edit',
                'id' => $this->prepareUrlPK($row)
            ));
            $deleteUrl = $this->url->raiseClone();
            $deleteUrl->params(array(
                'opt' => 'delete',
                'id' => $this->prepareUrlPK($row)
            ));
            $drow['Options'] = '<a href="' . $editUrl . '">Edit</a>&nbsp;<a href="'.$url.'">Delete</a>';
            $data->add($drow);
        }
        $table->data($data);
        $this->define('output', $table->output());
    }
    
    private function buildDelete(){
        $this->define('output', '');
    }
    
}